
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>常见问题 - vue.js</title>
        <meta charset="utf-8">
        <meta name="description" content="Vue.js - Intuitive, Fast and Composable MVVM for building interactive interfaces.">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <!-- <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Source+Code+Pro|Dosis:300,500' rel='stylesheet' type='text/css'> -->
        <link rel="icon" href="/images/logo.png" type="image/x-icon">
        <script>
            window.PAGE_TYPE = "教程"
        </script>
        <link rel="stylesheet" href="/css/page.css" type="text/css">
        <script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-46852172-1', 'vuejs.org');
  ga('send', 'pageview');
</script>
        <script src="/js/vue.js"></script>
    </head>
    <body>
        <div id="mobile-bar">
            <a class="menu-button"></a>
            <a class="logo" href="/"></a>
        </div>
        
            <div id="header">
    <a id="logo" href="/">
        <img src="/images/logo.png">
        <span>Vue.js</span>
    </a>
    <ul id="nav">
        <li>
  <form id="search-form">
    <input type="text" id="search-query" class="st-default-search-input">
  </form>
</li>
<li><a href="/guide/" class="nav-link current">教程</a></li>
<li><a href="/api/" class="nav-link">API</a></li>
<li><a href="/examples/" class="nav-link">示例</a></li>
<li><a href="/blog/" class="nav-link">Blog</a></li>
<li><a href="https://github.com/yyx990803/vue" target="_blank" class="nav-link">GitHub</a></li>

    </ul>
</div>
            <div id="main">
                
                    
    <div class="sidebar">
    <ul class="main-menu">
        <li>
  <form id="search-form">
    <input type="text" id="search-query" class="st-default-search-input">
  </form>
</li>
<li><a href="/guide/" class="nav-link current">教程</a></li>
<li><a href="/api/" class="nav-link">API</a></li>
<li><a href="/examples/" class="nav-link">示例</a></li>
<li><a href="/blog/" class="nav-link">Blog</a></li>
<li><a href="https://github.com/yyx990803/vue" target="_blank" class="nav-link">GitHub</a></li>

    </ul>
    <div class="list">
        <h2>教程</h2>
        <ul class="menu-root">
            
                <li>
                    <a href="/guide/installation.html" class="sidebar-link">安装</a>
                </li>
            
                <li>
                    <a href="/guide/index.html" class="sidebar-link">起步</a>
                </li>
            
                <li>
                    <a href="/guide/directives.html" class="sidebar-link">指令</a>
                </li>
            
                <li>
                    <a href="/guide/filters.html" class="sidebar-link">过滤器</a>
                </li>
            
                <li>
                    <a href="/guide/list.html" class="sidebar-link">列表渲染</a>
                </li>
            
                <li>
                    <a href="/guide/events.html" class="sidebar-link">事件监听</a>
                </li>
            
                <li>
                    <a href="/guide/forms.html" class="sidebar-link">处理表单</a>
                </li>
            
                <li>
                    <a href="/guide/computed.html" class="sidebar-link">计算属性</a>
                </li>
            
                <li>
                    <a href="/guide/custom-directive.html" class="sidebar-link">自定义指令</a>
                </li>
            
                <li>
                    <a href="/guide/custom-filter.html" class="sidebar-link">自定义过滤器</a>
                </li>
            
                <li>
                    <a href="/guide/components.html" class="sidebar-link">组件系统</a>
                </li>
            
                <li>
                    <a href="/guide/transitions.html" class="sidebar-link">过渡效果</a>
                </li>
            
                <li>
                    <a href="/guide/application.html" class="sidebar-link">创建大型应用</a>
                </li>
            
                <li>
                    <a href="/guide/extending.html" class="sidebar-link">扩展 Vue</a>
                </li>
            
                <li>
                    <a href="/guide/best-practices.html" class="sidebar-link new">细节与最佳实践</a>
                </li>
            
                <li>
                    <a href="/guide/faq.html" class="sidebar-link current">常见问题</a>
                </li>
            
            <li><a href="http://legacy.vuejs.org">旧版 0.11 文档</a></li>
            <li style="margin:10px 0 3px">
              <script data-gittip-username="yyx990803"
                data-gittip-widget="button"
                src="//gttp.co/v1.js"></script>
            </li>
        </ul>
    </div>
</div>


<div class="content 教程 with-sidebar">
    <h1>常见问题</h1>
    <div id="ad">
        <script async type="text/javascript" src="//cdn.carbonads.com/carbon.js?zoneid=1673&serve=C6AILKT&placement=vuejs" id="_carbonads_js"></script>
    </div>
    <ul>
<li><p><strong>为什么 Vue.js 不支持 IE8?</strong></p>
<p>Vue.js 借助 ECMASCript 5 的 <code>Object.defineProperty</code> 才得以不靠脏检查实现原生对象即模型的 API。然而这一新特性在 IE8 里只在 DOM 元素上起作用，对原生 JavaScript 对象无效，而且无法通过 polyfill 来修正。</p>
</li>
<li><p><strong>那么 Vue.js 修改了我的数据喽?</strong></p>
<p>是，也不是。Vue.js 只是将正常属性转化为 getters 和 setters，这样它才能在属性被访问或更改时得到通知。而在序列化数据时，结果是完全相同的。当然，这里有一些注意事项：</p>
<ol>
<li><p>当你使用 <code>console.log</code> 观察对象时你将只能看到一串 getter/setters. 但你可以使用 <code>vm.$log()</code> 来打印出一个更直观的输出。</p>
</li>
<li><p>你不能在数据对象里定义自己的 getter/setters。这通常来说不是问题，因为数据对象应该是从纯 JSON 中解析出来的，而且 Vue.js 提供了计算属性功能。</p>
</li>
<li><p>Vue.js 在被观察的对象上添加了一些拓展的属性或方法，比如 <code>__ob__</code>, <code>$add</code>, <code>$set</code> 以及 <code>$delete</code>。这些属性是不可遍历的，所以它们不会显示在 <code>for ... in ...</code> 循环中。只要你不覆盖它们，就不会有什么问题。</p>
</li>
</ol>
<p>除此之外，访问属性和赋值都和原生对象一样, <code>JSON.stringify</code> 和 <code>for ... in ...</code> 循环也能够照常运行。99.9% 的情况下你都不需要考虑这些问题。</p>
</li>
<li><p><strong>Vue.js 目前的状态怎样? 我能把它应用在生产环境中么?</strong></p>
<p>Vue.js 最新的 0.12 发布版本，经历了一些API变更，但这是 1.0 版本前的最后一个计划发布版本。与此同时，全球各地都已经有公司/产品将 Vue.js 使用在了生产环境中。Vue.js 的测试覆盖率和 bug 修复速度也在同类框架中是首屈一指的。参见：<a href="https://github.com/yyx990803/vue/wiki/Projects-Using-Vue.js" target="_blank" rel="external">使用了 Vue.js 的项目（不完全列表）</a>。</p>
</li>
<li><p><strong>Vue.js 是完全免费的吗?</strong></p>
<p>Vue.js 基于 MIT 协议发布，是完全开源且免费的。</p>
</li>
<li><p><strong>Vue.js 和 AngularJS 之间的区别是什么?</strong></p>
<p>下面是一些选择 Vue 而不是 Angular 的可能原因，当然它们可能不适用于每一个人：</p>
<ol>
<li><p>Vue.js 是一个更加灵活开放的解决方案。它允许你以希望的方式组织你的应用程序，而不是任何时候都必须遵循 Angular 制定的规则。它仅仅是一个视图层，所以你可以将它嵌入一个现有页面而不一定要做成一个庞大的单页应用。在结合其他库方面它给了你更大的的空间，但相应，你也需要做更多的架构决策。例如，Vue.js核心默认不包含路由和 ajax 功能，并且通常假定你在用应用中使用了一个外部的模块构建系统。这可能是最重要的区别。</p>
</li>
<li><p>在 API 和内部设计方面，Vue.js 比 Angular 简单得多, 因此你可以快速地掌握它的全部特性并投入开发。</p>
</li>
<li><p>Vue.js 拥有更好的性能，因为它不使用脏检查。当 watcher 越来越多时, Angular 会变得越来越慢，因为作用域内的每一次数据变更，所有的 watcher 都需要被重新求值。Vue 则根本没有这个问题，因为它采用的是基于依赖追踪的观察系统，所以所有的数据变更触发都是独立的，除非它们之间有明确的依赖关系。</p>
</li>
<li><p>Vue.js 中指令和组件的概念区分得更为清晰。指令只负责封装 DOM 操作，而组件代表一个自给自足的独立单元 —— 它拥有自己的视图和数据逻辑。在 Angular 中它们两者间有不少概念上的混淆。</p>
</li>
</ol>
<p>当然，需要指出的是 Vue.js 还是一个相对年轻的项目，而 Angular 经受过大量的实战检验，并且背后有谷歌支持，还有一个更大的社区。</p>
</li>
<li><p><strong>Vue.js 和 React.js 有什么区别?</strong></p>
<p>React.js 和 Vue.js 确实有一些相似 —— 它们都提供数据驱动、可组合搭建的视图组件。然而，它们的内部实现是完全不同的。React 是基于  Virtual DOM —— 一种在内存中描述 DOM 树状态的数据结构。React 中的数据通常被看作是不可变的，而 DOM 操作则是通过 Virtual DOM 的 diff 来计算的。与之相比，Vue.js 中的数据默认是可变的，而数据的变更会直接出发对应的 DOM 更新。相比于 Virtual DOM，Vue.js 使用实际的 DOM 作为模板，并且保持对真实节点的引用来进行数据绑定。</p>
<p>Virtual DOM 提供了一个函数式的描述视图的方法，这很 cool。因为它不使用数据观察机制，每次更新都会重新渲染整个应用，因此从定义上保证了视图通与数据的同步。它也开辟了 JavaScript 同构应用的可能性。</p>
<p>实话实说，我自己对 React 的设计理念也是十分欣赏的。但 React 有一个问题就是组件的逻辑和视图结合得非常紧密。对于部分开发者来说，他们可能觉得这是个优点，但对那些像我一样兼顾设计和开发的人来说，还是更偏好模板，因为模板能让我们更好地在视觉上思考设计和 CSS。JSX 和 JavaScript 逻辑的混合干扰了我将代码映射到设计的思维过程。相反，Vue.js 通过在模板中加入一个轻量级的DSL (指令系统)，换来一个依旧直观的模板，且能够将逻辑封装进指令和过滤器中。</p>
<p>React的另一个问题是：由于 DOM 更新完全交由 Virtual DOM 管理，当你真的<strong>想要</strong>自己控制 DOM 时就有点棘手了（虽然理论上你可以，但这样做时你本质上在对抗 React 的设计思想）。对于需要复杂时间控制的动画来说这就变成了一项很讨人厌的限制。在这方面，Vue.js 允许更多的灵活性，并且有不少用 Vue.js 构建的富交互实例。参见<a href="https://github.com/yyx990803/vue/wiki/Projects-Using-Vue.js#interactive-experiences" target="_blank" rel="external">一些用 Vue.js 制作的 FWA/Awwwards 获奖站点</a></p>
</li>
<li><p><strong>Vue.js 和 Polymer 有什么区别?</strong></p>
<p>Polymer 是另一个由 Google 支持的项目，实际上也是 Vue.js 的灵感来源之一。Vue.js 的组件可以类比为 Polymer 中的自定义元素，它们都提供类似的开发体验。最大的不同在于，Polymer 依赖最新的 Web Components 特性，在不支持的浏览器中，需要加载笨重的 polyfill，性能也会受到影响。相对的，Vue.js 无需任何依赖，最低兼容到IE9。</p>
</li>
<li><p><strong>Vue.js 和 KnockoutJS 有什么区别?</strong></p>
<p>首先，Vue 提供了一个更清晰的语法来获取/设置 VM 属性。</p>
<p>在更高层面上，Vue 与 Knockout 的区别是，Vue 的组件系统鼓励你使用 自上而下、结构优先、声明式的设计策略，而不是从下而上过程式的创建 ViewModel。Vue 的源数据是一个纯对象，不包含逻辑，可以直接 JSON.stringify 并传给 post 请求。ViewModel 代理了数据对象。Vue 实例始终用原生数据绑定相应的 DOM 元素。Knockout 的 ViewModel 本质上是数据，Model 与 ViewModel 的界限非常模糊，很可能导致过于复杂的 ViewModel 逻辑。</p>
</li>
<li><p><strong>我想要参与!</strong></p>
<p>欢迎! 请阅读 <a href="https://github.com/yyx990803/vue/blob/master/CONTRIBUTING.md" target="_blank" rel="external">贡献指南</a>，或是加入 <a href="https://gitter.im/yyx990803/vue" target="_blank"><img src="https://badges.gitter.im/Join%20Chat.svg"></a> 参与讨论。</p>
</li>
</ul>

    <div class="footer">发现了问题或想要贡献？来 Github 给 Vue.js <a href="https://github.com/vuejs/vuejs.org" target="_blank">英文站点</a>或<a href="https://github.com/Jinjiang/vuejs.org/tree/lang-zh" target="_blank">中文翻译</a>来个 Fork 吧！</div>
</div>
                
            </div>
            <script src="/js/smooth-scroll.min.js"></script>
            <script src="/js/common.js"></script>
        

        <script src="https://cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js"></script><script src="https://cdn.jsdelivr.net/gh/shentao/vuejs-outdated-docs-modal@v1.3/prompt.min.js"></script>
        <script>
            document.addEventListener('DOMContentLoaded', function() {
                FastClick.attach(document.body);
            }, false);
        </script>
    </body>
</html>
